package com.my.thread_pool;

import com.alibaba.fastjson.JSON;
import org.apache.commons.collections4.list.CursorableLinkedList;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class MyThreadPoolExecutor{


    private ThreadPoolExecutor myThreadPoolExecutor;

    private BlockingQueue<HandlerTask> tasks = new LinkedBlockingQueue<>();

    public MyThreadPoolExecutor(int corePoolSize,
                                int maximumPoolSize,
                                long keepAliveTime,
                                TimeUnit unit,
                                BlockingQueue<Runnable> workQueue,
                                RejectedExecutionHandler rejectedExecutionHandler) {

        myThreadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime,unit, workQueue, rejectedExecutionHandler);

        //
        //myThreadPoolExecutor.prestartAllCoreThreads();
    }


    public void execute(){

        if(tasks.size() == 1){

            tasks.iterator().next().execute();
        }else{

            parallelExecute(tasks);
        }
    }

    /**
     * 多线程执行
     *
     * @param tasks
     *@throws
     */
    private void parallelExecute(BlockingQueue<HandlerTask> tasks) {

        CountDownLatch countDownLatch = new CountDownLatch(tasks.size());

        try {
            for (HandlerTask task : tasks) {
                myThreadPoolExecutor.submit(() -> {
                    task.execute();
                    countDownLatch.countDown();
                });
            }
            countDownLatch.await(5000, TimeUnit.MILLISECONDS);
            //countDownLatch.await() 表示上面的线程执行完之后才能执行下面的
            System.out.println("en==========");
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    /**
     * 添加到task列表中
     *
     * @param task
     */
    public void add(final HandlerTask task) {
        if (null != task) {
            tasks.add(task);
        }
    }


    public static void main(String[] args) {

        Long startTime = System.currentTimeMillis();
        MyThreadPoolExecutor myThreadPoolExecutor = new MyThreadPoolExecutor(10, 100,
                1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

        UserInfoDetalImpl userInfoDetal = new UserInfoDetalImpl();
        UserInfoDetalImpl2 userInfoDetal2 = new UserInfoDetalImpl2();
        UserInfoDetalImpl3 userInfoDetal3 = new UserInfoDetalImpl3();
        List<UserInfo> userInfoList = new ArrayList<>();

        /*try {
            userInfoList.add(new UserInfo(1, "zlx", "123456"));
            userInfoList.add(new UserInfo(2, "clock", "123456"));
            userInfoList.add(new UserInfo(3, "frost", "123456"));
            userInfoList.add(new UserInfo(4, "vacant", "123456"));

            userInfoList.stream().forEach(userInfo -> {
                int res = 0;
                userInfoDetal.dealUserInfo(myThreadPoolExecutor, userInfo, res);
                System.out.println("result is:====" + res);
            });
            myThreadPoolExecutor.execute();
        }catch (Exception e){

        }*/

        //List<UserInfo> newUserInfoList = new CursorableLinkedList<>();
        Map<String,UserInfo> map = new ConcurrentHashMap<>();
        try {
            userInfoList.add(new UserInfo(1, "zlx", "123456"));
            userInfoList.add(new UserInfo(2, "clock", "123456"));
            userInfoList.add(new UserInfo(3, "frost", "123456"));
            userInfoList.add(new UserInfo(4, "vacant", "123456"));

            userInfoList.stream().forEach(userInfo -> {
                final UserInfo res = new UserInfo();
                userInfoDetal3.dealUserInfo(myThreadPoolExecutor, userInfo, map);
                //newUserInfoList.add(res);

            });
            myThreadPoolExecutor.execute();

        }catch (Exception e){
            e.printStackTrace();
        }

        //System.out.println("========" + JSON.toJSONString(newUserInfoList));
        System.out.println("map ======" + JSON.toJSONString(map));
        System.out.println("===================" + (System.currentTimeMillis() - startTime)/1000);
        System.out.println("final count========" + myThreadPoolExecutor.myThreadPoolExecutor.getActiveCount());
    }
}